﻿using Furion.DependencyInjection;
using Furion.FriendlyException;
using System.Reflection;
namespace EMC.VISITOR.Application;
/// <summary>
/// 訪客黑名單服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public partial class VistLogBlackService : IDynamicApiController, ITransient
{
    protected readonly SqlSugarRepository<VistLogBlack> _rep;
    protected readonly SqlSugarRepository<SysDictType> _repDType;
    public VistLogBlackService(SqlSugarRepository<VistLogBlack> rep,SqlSugarRepository<SysDictType> repDType)
    {
        _rep = rep;
        _repDType = repDType;
    }
    #region 代码生成
    /// <summary>
    /// 分页查询訪客黑名單
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    public  virtual async Task<SqlSugarPagedList<VistLogBlackOutput>> Page(VistLogBlackInput input)
    {
      var context = _rep.AsQueryable().FilterDelete();
      if (context.UseCustomeSelectFlag())
      {
          return await context.CustomToSelect<VistLogBlack,VistLogBlackOutput>(input);
      }
      else
      {


        var query= context.CustomWhere(input)
            .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
                u.Name.Contains(input.SearchKey.Trim())
                || u.IdCard.Contains(input.SearchKey.Trim())
                || u.Company.Contains(input.SearchKey.Trim())
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.IdCard), u => u.IdCard.Contains(input.IdCard.Trim()))
            .WhereIF(input.CompanyList!=null &&input.CompanyList.Count>0, u =>input.CompanyList.Contains(u.Company))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Company), u => u.Company.Contains(input.Company.Trim()))
        .WhereIF(input.IsEnabled.HasValue, u => u.IsEnabled == input.IsEnabled)
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<SysUser>((u, createuserid) => u.CreateUserId == createuserid.Id , SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .LeftJoin<SysUser>((u, createuserid, updateuserid) => u.UpdateUserId == updateuserid.Id , SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .Select((u, createuserid, updateuserid)=> new VistLogBlackOutput{
                Id = u.Id, 
                Name = u.Name, 
                IdCard = u.IdCard, 
                IdCardImg = u.IdCardImg, 
                Company = u.Company, 
                StartTime = u.StartTime, 
                EndTime = u.EndTime, 
                IsEnabled = u.IsEnabled, 
                Remark = u.Remark, 
                CreateTime = u.CreateTime, 
                UpdateTime = u.UpdateTime, 
                CreateUserId = u.CreateUserId, 
                CreateUserIdRealName = createuserid.RealName,
                UpdateUserId = u.UpdateUserId, 
                UpdateUserIdRealName = updateuserid.RealName,
            }).OrderByIF(input.Field.IsNullOrEmpty() && typeof(VistLogBlack).GetProperties().Any(pp => pp.Name == nameof(VistLogBlack.CreateTime) && (pp.GetCustomAttribute<SugarColumn>() == null || pp.GetCustomAttribute<SugarColumn>().IsIgnore == false)), u => u.CreateTime, OrderByType.Desc)
            //.Mapper(c => c.IdCardImgAttachment, c => c.IdCardImg)
;
        if(input.StartTimeRange != null && input.StartTimeRange.Count >0)
        {
            DateTime? start= input.StartTimeRange[0]; 
            query = query.WhereIF(start.HasValue, u => u.StartTime > start);
            if (input.StartTimeRange.Count >1 && input.StartTimeRange[1].HasValue)
            {
                var end = input.StartTimeRange[1].Value.AddDays(1);
                query = query.Where(u => u.StartTime < end);
            }
        } 
        if(input.EndTimeRange != null && input.EndTimeRange.Count >0)
        {
            DateTime? start= input.EndTimeRange[0]; 
            query = query.WhereIF(start.HasValue, u => u.EndTime > start);
            if (input.EndTimeRange.Count >1 && input.EndTimeRange[1].HasValue)
            {
                var end = input.EndTimeRange[1].Value.AddDays(1);
                query = query.Where(u => u.EndTime < end);
            }
        } 
        query = query.CustomeOrder(input);
        return await query.CustomToPagedListAsync(input);
      }
    }

    /// <summary>
    /// 增加訪客黑名單
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    public virtual async Task<JRResult<string>> Add(AddVistLogBlackInput input)
    {
        var entity = input.Adapt<VistLogBlack>();
         var doSomeResult = await  entity.DoSomeThing(_rep.Context);
        if (!doSomeResult.Item1)
            return CustomeResult.Fail<string>(doSomeResult.Item2);
        bool isNeedReplicatings=false;
        string repString=null;
        Expression<Func<VistLogBlack, bool>> whereExpression = r => true;
        whereExpression = whereExpression.And(r => r.IdCard == entity.IdCard && !SqlFunc.IsNullOrEmpty(r.IdCard));
        isNeedReplicatings=true;
        repString+="黑名单证件号";
         if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings){
              await _rep.InsertAsync(entity);
            }
            else
            {
                //系统中存在已删除数据，还原数据
                whereExpression = whereExpression.And(r => r.IsDelete == true);
                var exsitModel = await _rep.GetFirstAsync(whereExpression);
                if (exsitModel != null)
                {
                    entity.Id = exsitModel.Id; //还原已删除的数据
                    entity.IsDelete = false;
                       await _rep.UpdateAsync(entity);
                    isNeedReplicatings = false;
                }
            }
        }
        else{
              await _rep.InsertAsync(entity);
        }
        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "新增成功！" : $"系统中存在重复的【{repString}】，不能重复添加！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 删除訪客黑名單
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    public virtual async Task Delete(DeleteVistLogBlackInput input)
    {
        var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _rep.FakeDeleteAsync(entity);   //假删除
    }

    /// <summary>
    /// 更新訪客黑名單
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    public virtual async Task<JRResult<string>> Update(UpdateVistLogBlackInput input)
    {
        var entity = input.Adapt<VistLogBlack>();
        var doSomeResult = await  entity.DoSomeThing(_rep.Context);
        if (!doSomeResult.Item1)
            return CustomeResult.Fail<string>(doSomeResult.Item2);
        bool isNeedReplicatings = false;
        string repString=null;
        Expression<Func<VistLogBlack, bool>> whereExpression = r => r.Id != entity.Id;
        whereExpression = whereExpression.And(r => r.IdCard == entity.IdCard && !SqlFunc.IsNullOrEmpty(r.IdCard));
        isNeedReplicatings=true;
        repString+="黑名单证件号";
         if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings){
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
            }
        }
        else
           {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
           }

        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "更新成功！" : $"系统中存在重复的【{repString}】，不能修改！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 保存訪客黑名單
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Save")]
    public virtual async Task<JRResult<string>> Save(UpdateVistLogBlackInput input)
    {
        var entity = input.Adapt<VistLogBlack>();
        await  entity.SaveDoSomeThing(_rep.Context);
        bool isNeedReplicatings = false;
        string repString=null;
        Expression<Func<VistLogBlack, bool>> whereExpression = r => r.Id != entity.Id;
        whereExpression = whereExpression.And(r => r.IdCard == entity.IdCard && !SqlFunc.IsNullOrEmpty(r.IdCard));
        isNeedReplicatings=true;
        repString+="黑名单证件号";
         if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings)
               {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
               }
        }
        else
            {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
            }

        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "更新成功！" : $"系统中存在重复的【{repString}】，不能修改！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

        /// <summary>
    /// 保存訪客黑名單包含关联表
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "SaveWithChildren")]
    public virtual async Task<JRResult<string>> SaveWithChildren(VistLogBlack entity)
    {
        await  entity.SaveDoSomeThing(_rep.Context);
        bool isNeedReplicatings = false;
        string repString=null;
        Expression<Func<VistLogBlack, bool>> whereExpression = r => r.Id != entity.Id;
        whereExpression = whereExpression.And(r => r.IdCard == entity.IdCard && !SqlFunc.IsNullOrEmpty(r.IdCard));
        isNeedReplicatings=true;
        repString+="黑名单证件号";
         if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings)
               {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
               }
        }
        else
            {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
            }

        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "更新成功！" : $"系统中存在重复的【{repString}】，不能修改！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 获取訪客黑名單
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    public virtual async Task<VistLogBlack> Get([FromQuery] QueryByIdVistLogBlackInput input)
    {
        return await _rep.GetFirstAsync(u => u.Id == input.Id);
    }

     /// <summary>
    /// 获取訪客黑名單详情
    /// </summary>
    [HttpGet]
    public virtual async Task<dynamic> Info(string tableName, long id)
    {
        var logConfigId = SqlSugarConst.GetDataBaseConfigId(tableName);
        if (logConfigId.IsNullOrEmpty())
            return new { };
        var _db = _rep.AsTenant().GetConnectionScope(logConfigId);
        var tableInfo = SqlSugarConst.GetDdataBaseFullName(tableName);
        var dt = await _db.SqlQueryable<dynamic>($"select * from {tableInfo} where Id={id}").ToListAsync();
        dynamic clay = Clay.Object(dt.FirstOrDefault());
        return TypeHelper.SetDynamicZh(SqlSugarConst.GetModelName(tableName), clay);
    }

    /// <summary>
    /// 获取訪客黑名單列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    public async Task<List<VistLogBlackOutput>> List([FromQuery] VistLogBlackInput input)
    {
        return await _rep.AsQueryable().Select<VistLogBlackOutput>().ToListAsync();
    }

    /// <summary>
    /// 获取Flow系统公司名称列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "FlowSystemSGCompanyDropdown"), HttpPost]
    [AllowAnonymous]
    public async Task<dynamic> FlowSystemSGCompanyDropdown(VistLogBlack model=null)
    {
        var logConfigId = SqlSugarConst.GetDataBaseConfigId(typeof(FlowSystemSG));
        var _db = _rep.AsTenant().GetConnectionScope(logConfigId);
        var query = _db.Queryable<FlowSystemSG>();
        if (query.UseDropDownCustomeSelectFlag())
        {
            return await query.UseDropDownCustomeSelect(model);
        }
        else
        {
        return await query.DropDownQuery().GroupBy(u => new { u.supplier_name})
                .Select(u => new
                {
                    Label = u.supplier_name,
                    Value = u.supplier_name
                }
                ).ToListAsync();
        }
    }

    /// <summary>
    /// 上传证件照片
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [RequestSizeLimit(1024 * 1024 * 1000)]//设定请求大小为1GB（如需设置请求大小设置此特性）
    [ApiDescriptionSettings(Name = "UploadIdCardImg"), HttpPost]
    [AllowAnonymous]
    public virtual async Task<PropsHttpModel> UploadIdCardImg([Required] IFormFile file)
    {
            var service = App.GetService<SysFileService>();
            var model = await service.UploadFile(file, "upload/IdCardImg"); 
            return new PropsHttpModel
            {
                 fileId = model == null ? 0: model.Id,
                  url = model?.Url,
                 name = model==null?null:$"{model.Id}.{model.Suffix}",
                 fileName = model?.FileName,
                 home = model?.Url,
                  res = "result"
            };
    } 



    /// <summary>
    /// 导出訪客黑名單
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "Export"), NonUnify]
    public virtual async Task<IActionResult> Export(VistLogBlackInput input)
    {
          var context = _rep.AsQueryable().FilterDelete();
      if (context.UseCustomeSelectFlag())
      {
          var list= await context.CustomToSelectExport<VistLogBlack,ExportImportVistLogBlackDto>(input);
          IExcelExporter excelExporter = new ExcelExporter();
          var res = await excelExporter.ExportAsByteArray(list);
          return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "生产模式切换记录表.xlsx" };
      }
      else
      {

        var query= _rep.AsQueryable().FilterDelete().CustomWhere(input)
            .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
                u.Name.Contains(input.SearchKey.Trim())
                || u.IdCard.Contains(input.SearchKey.Trim())
                || u.Company.Contains(input.SearchKey.Trim())
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.IdCard), u => u.IdCard.Contains(input.IdCard.Trim()))
            .WhereIF(input.CompanyList!=null &&input.CompanyList.Count>0, u =>input.CompanyList.Contains(u.Company))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Company), u => u.Company.Contains(input.Company.Trim()))
        .WhereIF(input.IsEnabled.HasValue, u => u.IsEnabled == input.IsEnabled)
            //处理外键和TreeSelector相关字段的连接
           
            .LeftJoin<SysUser>((u, createuserid) => u.CreateUserId == createuserid.Id , SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .LeftJoin<SysUser>((u, createuserid, updateuserid) => u.UpdateUserId == updateuserid.Id , SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .Select((u, createuserid, updateuserid)=> new ExportImportVistLogBlackDto{
                Name = u.Name, 
                IdCard = u.IdCard, 
                IdCardImg = u.IdCardImg, 
                Company = u.Company, 
                StartTime = u.StartTime, 
                EndTime = u.EndTime, 
                IsEnabled = u.IsEnabled, 
                Remark = u.Remark, 
                CreateTime = u.CreateTime, 
                UpdateTime = u.UpdateTime, 
                CreateUserId = u.CreateUserId, 
                CreateUserIdRealName = createuserid.RealName,
                UpdateUserId = u.UpdateUserId, 
                UpdateUserIdRealName = updateuserid.RealName,
            })
            //.Mapper(c => c.IdCardImgAttachment, c => c.IdCardImg)
;
        if(input.StartTimeRange != null && input.StartTimeRange.Count >0)
        {
            DateTime? start= input.StartTimeRange[0]; 
            query = query.WhereIF(start.HasValue, u => u.StartTime > start);
            if (input.StartTimeRange.Count >1 && input.StartTimeRange[1].HasValue)
            {
                var end = input.StartTimeRange[1].Value.AddDays(1);
                query = query.Where(u => u.StartTime < end);
            }
        } 
        if(input.EndTimeRange != null && input.EndTimeRange.Count >0)
        {
            DateTime? start= input.EndTimeRange[0]; 
            query = query.WhereIF(start.HasValue, u => u.EndTime > start);
            if (input.EndTimeRange.Count >1 && input.EndTimeRange[1].HasValue)
            {
                var end = input.EndTimeRange[1].Value.AddDays(1);
                query = query.Where(u => u.EndTime < end);
            }
        } 

        query = query.CustomeOrder(input);
        var list=await query.ToListAsync();
        IExcelExporter excelExporter = new ExcelExporter();
        var res = await excelExporter.ExportAsByteArray(list);
        return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "訪客黑名單.xlsx" };
     }
  }

     /// <summary>
    /// 导入
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [HttpPost]
    public virtual async Task<JRResult<string>> Import(IFormFile file)
    {
        IImporter Importer = new ExcelImporter();
        var importData = await Importer.Import<ExportImportVistLogBlackDto>(file.OpenReadStream());
        if (importData.HasError == true) { return CustomeResult.Fail<string>("导入错误");  }
        if (importData.Exception != null) { return CustomeResult.Fail<string>(importData.Exception.ToString());  }
        if (importData.RowErrors.Count > 0) { return CustomeResult.Fail<string>(JSON.Serialize(importData.RowErrors));  }
        if (importData.Data == null) {return CustomeResult.Fail<string>("导入的数据量不能为空！");  }
        if (importData.Data.Count <= 0) { return CustomeResult.Fail<string>("导入的数据量为0个！"); }
       
            var models = importData.Data.Adapt<List<VistLogBlack>>();
            bool isNeedReplicatings = false;
            string repString=null;
            Expression<Func<VistLogBlack, bool>> whereExpression = r => true;
             whereExpression = whereExpression.And(r => models.Select(c => c.IdCard).Contains(r.IdCard));
             isNeedReplicatings=true;
             repString+="【黑名单证件号重复】";
             if(models.GroupBy(r=>r.IdCard).Any(c=>c.Count()>1)){return CustomeResult.Fail<string>(repString);}
              if (isNeedReplicatings)
             {
                 isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
                
                 if (!isNeedReplicatings){
                      await _rep.AsInsertable(models).ExecuteCommandAsync();
                 }
                 else
                      return CustomeResult.Fail<string>(repString);
             }else{
                      await _rep.AsInsertable(models).ExecuteCommandAsync();
             }
        
           return CustomeResult.SuccessNotShowMessage<string>();
    }


    /// <summary>
    /// 模板下载
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet]
    public virtual async Task<IActionResult> TemplateDown()
    {
        IImporter Importer = new ExcelImporter();
        var template = await Importer.GenerateTemplateBytes<ExportImportVistLogBlackDto>();
        return new FileStreamResult(new MemoryStream(template), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "訪客黑名單导入模板.xlsx" };
    }
#endregion
}

